/** utils about other common opration should be write here */
import md5 from "md5"
import dayjs from "dayjs"
import type { ConfigType, QUnitType, OpUnitType } from "dayjs"
import Taro from "@tarojs/taro"

export function dateFormat(date?: ConfigType, format = "YYYY-MM-DD"): string {
  return dayjs(date).format(format)
}

export function fromNowOn(
  date?: ConfigType,
  unit?: QUnitType | OpUnitType,
  float?: boolean
): number {
  return dayjs().diff(date, unit, float)
}

/** 获取到现在的间隔天数 */
export function getIntervalDays(date: ConfigType): number {
  return this.fromNowOn(date, "day")
}

export function encodeMd5(str: string): string {
  return md5(str)
}

export function trim(str: string): string {
  return str.replace(/(^\s*)|(\s*$)/g, "")
}

export function debounce(fn: Function, delay = 300): Function {
  let timer: NodeJS.Timer
  return function () {
    if (timer) {
      clearTimeout(timer)
    }
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    const ctx = this
    // eslint-disable-next-line prefer-rest-params
    const args = Array.prototype.slice.call(arguments)
    timer = setTimeout(() => {
      fn.apply(ctx, args)
    }, delay)
  }
}

export function throttle(fn: Function, delay = 300): Function {
  let timer: NodeJS.Timeout
  let valid = true
  return function () {
    if (!valid) {
      return
    }
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    const ctx = this
    // eslint-disable-next-line prefer-rest-params
    const args = Array.prototype.slice.call(arguments)
    valid = false
    timer = setTimeout(() => {
      fn.apply(ctx, args)
      valid = true
      // avoid memory leak
      clearTimeout(timer)
    }, delay)
  }
}
/**
 * 序列化query对象转为query string查询参数
 * @param query query 对象
 * @param withPrefix 是否添加“？”
 * ```ts
 * const qs = querySerialize({a: 1, b: 2})
 * expect(qs).toBe("a=1&b=2")
 * ```
 */
export function querySerialize(query: Recordable, withPrefix = false): string {
  if (!query) return ""
  const keys = Object.keys(query)
  if (keys.length === 0) return ""
  const prefix = withPrefix ? "?" : ""
  return keys.reduce((prev, next) => {
    return `${prev}${next}=${query[next]}&`
  }, prefix)
}
/**
 * 反序列化query string查询参数转为query对象
 * @param querystring querystring查询参数
 * ```ts
 * const qs = queryParse("a=1&b=2")
 * expect(qs).toBe({a: 1, b: 2})
 * ```
 */
export function queryParse(querystring: string): Recordable {
  if (!querystring) return {}
  querystring = querystring.replace(/^\?/, "")
  const recorder = {} as { [key: string]: any[] }
  querystring.split("&").forEach(entry => {
    const [key, val] = entry.split("=")
    if (!recorder[key]) {
      recorder[key] = []
    }
    recorder[key].push(val)
  })
  const result: Recordable = {}
  Object.keys(recorder).forEach(key => {
    if (recorder[key].length > 1) {
      result[key] = recorder[key]
    } else {
      result[key] = recorder[key][0]
    }
  })
  return result
}
export function normalizePrice(price: number | string) {
  price = Number(price)
  if (price - Math.trunc(price) !== 0) {
    return price
  }
  return Math.trunc(price)
}
export function prettyNum(num: number | string) {
  const n = Number(num)
  if (!n && n !== 0) return num
  return String(num).replace(/\B(?=(\d{3})+(?!\d))/g, ",")
}
export function cloneDeep<T>(value: T): T {
  return JSON.parse(JSON.stringify(value))
}
/** 设置页面meta信息
 * @mark only for swan
 */
export function setPageMeta(option: Taro.setPageInfo.Option) {
  if (process.env.TARO_ENV === "swan") {
    Taro.setPageInfo(option)
  }
}
export const formatRichText = (html: string) => {
  let newContent = html.replace(/<img[^>]*>/gi, function (match) {
    // match = match.replace(/style="[^"]+"/gi, "").replace(/style='[^']+'/gi, "")
    match = match.replace(/width="[^"]+"/gi, "").replace(/width='[^']+'/gi, "")
    match = match.replace(/height="[^"]+"/gi, "").replace(/height='[^']+'/gi, "")
    match = match.replace(/class=("|')[^\"\']+\1/gi, "") // remove class attribute directly
    return match
  })

  newContent = html.replace(/<p[^>]*>/gi, function (match) {
    // match = match.replace(/style="[^"]+"/gi, "").replace(/style='[^']+'/gi, "")
    match = match.replace(/class=("|')[^\"\']+\1/gi, "") // remove class attribute directly
    return match
  })

  newContent = html.replace(/<span[^>]*>/gi, function (match) {
    // match = match.replace(/style="[^"]+"/gi, "").replace(/style='[^']+'/gi, "")
    match = match.replace(/class=("|')[^\"\']+\1/gi, "") // remove class attribute directly
    return match
  })
  // newContent = newContent.replace(/style="[^"]+"/gi,function(match,capture){
  //   match = match.replace(/width:[^;]+;/gi, 'max-width:100%;').replace(/width:[^;]+;/gi, 'max-width:100%;');
  //   return match;
  // });
  //  newContent = newContent.replace(/\<img/gi, '<img style="max-width:100%;height:auto;display:block;margin-top:0;margin-bottom:0;"');

  newContent = newContent.replace(/\<img/gi, '<img class="h5-img"')
  newContent = newContent.replace(/\<p/gi, '<p class="h5-p"')
  newContent = newContent.replace(/\<span/gi, '<span class="h5-span"')
  newContent = newContent.replace(/\<div/gi, '<div class="h5-div"')
  newContent = newContent.replace(/\<strong/gi, '<strong class="h5-strong"')
  newContent = newContent.replace(/\<table/gi, '<table class="h5-table"')
  newContent = newContent.replace(/\<thead/gi, '<thead class="h5-thead"')
  newContent = newContent.replace(/\<tbody/gi, '<tbody class="h5-tbody"')
  newContent = newContent.replace(/\<tfoot/gi, '<tfoot class="h5-tfoot"')
  newContent = newContent.replace(/\<th/gi, '<th class="h5-th"')
  newContent = newContent.replace(/\<tr/gi, '<tr class="h5-tr"')
  newContent = newContent.replace(/\<td/gi, '<td class="h5-td"')
  newContent = newContent.replace(/\<h1/gi, '<h1 class="h5-h1"')
  newContent = newContent.replace(/\<h2/gi, '<h2 class="h5-h2"')
  newContent = newContent.replace(/\<h3/gi, '<h3 class="h5-h3"')
  newContent = newContent.replace(/\<h4/gi, '<h4 class="h5-h4"')
  newContent = newContent.replace(/\<h5/gi, '<h5 class="h5-h5"')
  newContent = newContent.replace(/\<h6/gi, '<h6 class="h5-h6"')
  newContent = newContent.replace(/\<a/gi, '<a class="h5-a"')

  // newContent = newContent.replace(/\<br\s?\/?\>/gi, "")
  return newContent
}
/***
 * @description 移除富文本所有标签和换行符(\n)
 */
export const stripHtmlTag = (html: string) => {
  // html tag
  const tagReg = /<.+?>/gim
  // \n
  const nlReg = /\n/gi
  // html entity
  const entityReg = /&.*?;/gi
  html = html.replace(tagReg, "")
  html = html.replace(nlReg, "")
  html = html.replace(entityReg, "")
  return html
}
export function noop() {}
